// import { request } from './xhr.js'
import { FileLoader } from 'three'
import JSZip from 'jszip'
import Loader from './loader'
import { isAndroid, isMobile } from '../host'
import { createIndexDB } from '@gaothing/indexdb-util'

// 安卓和pc环境使用indexdb存储zip模型文件
let indexdbObj = null
const modelVersion = import.meta.env.VITE_MODEL_VERSION
const useIndexdb = isAndroid() || !isMobile()
if (useIndexdb) {
  indexdbObj = await createIndexDB({
    name: 'modelsql', // 数据库的名称。
    version: 1, // 数据库的版本号。默认为1。 数据库的版本号。用于检测和升级数据库。
    storeList: [
      {
        // 要创建存储对象集合。在数据库中创建或访问对应的对象存储。
        name: 'models', // 存储对象的名称(表名)。在数据库中创建或访问对应的对象存储。
        keyPath: 'id', // 存储对象的键路径。默认为'id'。
        autoIncrement: false, // 是否自动为存储对象生成唯一递增的键。默认为true。
        indexs: [{ key: 'model', unique: true }, 'version'] // 索引列表,对象中key为索引名称，unique为是否唯一索引:true表示唯一索引  ,字符串为索引名称，unique默认 false
      }
    ]
  })
}

const getModel = (url, resolve, onProgress, reject) => {
  // request({
  //   url,
  //   onProgress
  // }).then(res => {
  //   resolve(res)
  // }).catch(err => {
  //   reject(err)
  // })
  const loader = new FileLoader()
  loader.setResponseType('arraybuffer')
  loader.load(url, resolve, onProgress, reject)
}

const ZipLoader = (url, onProgress, proxy) => {
  let hasModel = false
  let needUpdate = false
  return new Promise((resolve, reject) => {
    if (useIndexdb) {
      indexdbObj.getByKey(1).then(res => {
        if (res) {
          if (res.version === modelVersion) {
            hasModel = true
            resolve(res.model)
          } else {
            hasModel = false
            needUpdate = true
            proxy.$toast('首次加载模型，请耐心等待哦~')
            getModel(url, resolve, onProgress, reject)
          }
        } else {
          hasModel = false
          proxy.$toast('首次加载模型，请耐心等待哦~')
          getModel(url, resolve, onProgress, reject)
        }
      })
    } else {
      getModel(url, resolve, onProgress, reject)
    }
  }).then((buffer) => {
    if (useIndexdb) {
      if (!hasModel) {
        if (needUpdate) {
          indexdbObj.updateByKey({ id: 1, model: buffer, version: modelVersion })
        } else {
          indexdbObj.insert({ id: 1, model: buffer, version: modelVersion })
        }
      } else {
        onProgress({
          loaded: 1,
          total: 1
        })
      }
    }
    return JSZip.loadAsync(buffer)
  })
    .then((zip) => {
      const fileMap = {}
      const promiseArr = []
      const promise = JSZip.external.Promise
      for (const file in zip.files) {
        const entry = zip.file(file)
        if (entry === null) continue
        promiseArr.push(
          entry.async('blob').then((blob) => {
            fileMap[file] = URL.createObjectURL(blob)
          })
        )
      }
      return promise.all(promiseArr).then(() => fileMap)
    })
    .then((fileMap) => {
      return Loader(Object.keys(fileMap).map((key) => fileMap[key]))
    })
    .then((modelArr) => {
      return modelArr
    })
    .catch((error) => console.log(error))
}

const GlbLoader = (url, onProgress, proxy) => {
  const loader = new FileLoader()
  loader.setResponseType('blob')
  return new Promise((resolve, reject) => {
    loader.load(url, resolve, onProgress, reject)
  })
    .then((blob) => {
      const fileMap = {}
      fileMap['SZR.glb'] = URL.createObjectURL(blob)
      return fileMap
    })
    .then((fileMap) => {
      return Loader(Object.keys(fileMap).map((key) => fileMap[key]))
    })
    .then((modelArr) => {
      return modelArr
    })
    .catch((error) => console.log(error))
}

export default {
  ZipLoader,
  GlbLoader
}
